home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Deutsche Edition 1
/
Deutsche Edition 1.iso
/
amok
/
amok_lha
/
amok72.lha
/
while-Interpreter
/
Source
/
QuadInterpreter.MOD
< prev
next >
Wrap
Text File
|
1993-08-15
|
18KB
|
629 lines
(******************************
* Programm von Dieter Seidel *
* Eingegeben am 14.11.1991 *
* Nach einer langen Pause *
* fertiggestellt am 23.07.92 *
******************************)
IMPLEMENTATION MODULE QuadInterpreter;
FROM InOut IMPORT ReadCard, WriteCard, WriteLn, Write, WriteString;
FROM LongInOut IMPORT WriteLongCard;
FROM JaNein IMPORT JaNein;
FROM QuadLese IMPORT MaxZeile, QuadZeile, arrQuad, arrList;
FROM QuadDrucke IMPORT DruckeQuadrupel;
FROM QuadBerechneQuad IMPORT BerechneQuad;
CONST Max = 100; (* Die Variablen X[0]..X[99] sind für while-Programme *)
(* gedacht, während X[100] für Konstanten in den *)
(* while-Programmen sind. *)
MaxVar = 4;
VAR X : ARRAY [0..Max] OF CARDINAL;
AnzAnweisungen : LONGCARD;
PROCEDURE DruckeVariable(VAR X : ARRAY OF CARDINAL);
VAR i, Anzahl : CARDINAL;
BEGIN
Anzahl:=0;
FOR i:=0 TO 99 DO (* Bis Max, aber X[Max] steht für die Zahl null. *)
IF X[i] # 0 THEN
WriteString(" X[");WriteCard(i,2);WriteString("] : ");
WriteCard(X[i],5);
INC(Anzahl);
IF Anzahl = MaxVar THEN
WriteLn;
Anzahl:=0;
ELSE
WriteString(" : ");
END;
END;
END;
IF Anzahl # 0 THEN
WriteLn;
END;
END DruckeVariable;
PROCEDURE HoleVariable( QuadListe : arrQuad;
Zaehler : CARDINAL;
VAR VarEins, VarZwei : CARDINAL);
VAR i : CARDINAL;
BEGIN
i:=2;
VarEins:=0;
VarZwei:=0;
WHILE (QuadListe[Zaehler].Befehl[i] >= "0") AND
(QuadListe[Zaehler].Befehl[i] <= "9") AND (i <= MaxZeile) DO
VarEins:=VarEins * 10;
VarEins:=VarEins + ORD(QuadListe[Zaehler].Befehl[i]) - ORD("0");
INC(i);
END;
IF VarEins > 99 THEN
WriteLn;
WriteString("Zu grosser Variablen-Index!!! ");
DruckeQuadrupel(QuadListe[Zaehler]);
WriteLn;
HALT;
END;
WHILE NOT((QuadListe[Zaehler].Befehl[i] >= "0") AND
(QuadListe[Zaehler].Befehl[i] <= "9")) AND
(QuadListe[Zaehler].Befehl[i] # "X") AND
(i <= MaxZeile) DO
INC(i);
END;
IF i > MaxZeile THEN
WriteLn;
WriteString("Vermisse die zweite Anweisung!!!");
DruckeQuadrupel(QuadListe[Zaehler]);
WriteLn;
HALT;
END;
IF (QuadListe[Zaehler].Befehl[i] >= "0") AND
(QuadListe[Zaehler].Befehl[i] <= "9") THEN
X[Max]:=0;
WHILE (QuadListe[Zaehler].Befehl[i] >= "0") AND
(QuadListe[Zaehler].Befehl[i] <= "9") AND (i <= MaxZeile) DO
X[Max]:=10*X[Max];
X[Max]:=X[Max] + ORD(QuadListe[Zaehler].Befehl[i]) - ORD("0");
INC(i);
END;
VarZwei:=Max;
ELSE
INC(i);
IF i > MaxZeile THEN
WriteLn;
WriteString("Vermisse die zweite Anweisung!!!");
DruckeQuadrupel(QuadListe[Zaehler]);
WriteLn;
HALT;
END;
WHILE (QuadListe[Zaehler].Befehl[i] >= "0") AND
(QuadListe[Zaehler].Befehl[i] <= "9") AND (i <= MaxZeile) DO
VarZwei:=VarZwei * 10;
VarZwei:=VarZwei + ORD(QuadListe[Zaehler].Befehl[i]) - ORD("0");
INC(i);
END;
IF VarZwei > 99 THEN
WriteLn;
WriteString("Zu grosser Variablen-Index!!! ");
DruckeQuadrupel(QuadListe[Zaehler]);
WriteLn;
HALT;
END;
END;
END HoleVariable;
PROCEDURE succ(Zeile : QuadZeile) : BOOLEAN;
VAR i : CARDINAL;
BEGIN
FOR i:=1 TO MaxZeile DO
IF Zeile.Befehl[i] = "s" THEN
RETURN TRUE;
END;
END;
RETURN FALSE;
END succ;
PROCEDURE pred(Zeile : QuadZeile) : BOOLEAN;
VAR i : CARDINAL;
BEGIN
FOR i:=1 TO MaxZeile DO
IF Zeile.Befehl[i] = "p" THEN
RETURN TRUE;
END;
END;
RETURN FALSE;
END pred;
PROCEDURE schleife(Zeile : QuadZeile) : BOOLEAN;
VAR i : CARDINAL;
BEGIN
FOR i:=1 TO MaxZeile DO
IF Zeile.Befehl[i] = "#" THEN
RETURN TRUE;
END;
END;
RETURN FALSE;
END schleife;
PROCEDURE UnterprogrammNr(Zeile : QuadZeile) : CARDINAL;
VAR i,
Nummer : CARDINAL;
BEGIN
Nummer:=0;
i:=2;
WHILE (Zeile.Befehl[i] >= "0") AND
(Zeile.Befehl[i] <= "9") AND (i <= MaxZeile) DO
Nummer:=Nummer * 10;
Nummer:=Nummer + ORD(Zeile.Befehl[i]) - ORD("0");
INC(i);
END;
RETURN Nummer;
END UnterprogrammNr;
PROCEDURE BerUnterPrg(PrgNummer, Tiefe : CARDINAL;
QuadLst : arrQuad;
ZeigeUnterPrg : BOOLEAN);
VAR i,
VarEins,
VarZwei,
Anzahl,
Zaehler : CARDINAL; (* Zeigt auf die auszufuehrende Quadrupelzeile *)
QuadLst2 : arrQuad;
BefehlsLst : arrList;
Korrekt : BOOLEAN;
Y : ARRAY [0..Max] OF CARDINAL;
BEGIN
FOR i:=0 TO 9 DO
Y[i]:=X[i];
END;
FOR i:=10 TO Max DO
Y[i]:=0;
END;
Zaehler:=1;
Anzahl:=1;
WHILE QuadLst[Zaehler].Zeile # 0 DO
Korrekt:=FALSE;
IF ZeigeUnterPrg THEN
IF PrgNummer = 1 THEN
WriteString("Add");
END;
IF PrgNummer = 2 THEN
WriteString("Sub");
END;
IF PrgNummer = 3 THEN
WriteString("Mul");
END;
IF PrgNummer = 4 THEN
WriteString("DIV");
END;
IF PrgNummer = 5 THEN
WriteString("MOD");
END;
WriteCard(Tiefe,1);
WriteString(" : ");
WriteCard(Anzahl,3);
WriteString(" Quad : ");
DruckeQuadrupel(QuadLst[Zaehler]);
END;
IF QuadLst[Zaehler].Befehl[1] = "U" THEN
VarEins:=UnterprogrammNr(QuadLst[Zaehler]);
IF VarEins = 1 THEN
IF ZeigeUnterPrg THEN
WriteString(" U1 ---> Addition : X1:=X1+X2");WriteLn;
END;
BefehlsLst:="bX10:X2;wX10#0dbX10:p(X10);X1:s(X1)ee";
BerechneQuad(BefehlsLst,QuadLst2);
FOR i:=1 TO 9 DO X[i]:=Y[i]; END;
BerUnterPrg(VarEins,Tiefe+1,QuadLst2,ZeigeUnterPrg);
FOR i:=1 TO 9 DO Y[i]:=X[i]; END;
END;
IF VarEins = 2 THEN
IF ZeigeUnterPrg THEN
WriteString(" U2 ---> Subtraktion : X1:=X1-X2");WriteLn;
END;
BefehlsLst:="bX10:X2;wX10#0dbX10:p(X10);X1:p(X1)ee";
BerechneQuad(BefehlsLst,QuadLst2);
FOR i:=1 TO 9 DO X[i]:=Y[i]; END;
BerUnterPrg(VarEins,Tiefe+1,QuadLst2,ZeigeUnterPrg);
FOR i:=1 TO 9 DO Y[i]:=X[i]; END;
END;
IF VarEins = 3 THEN
IF ZeigeUnterPrg THEN
WriteString(" U3 ---> Multiplikation : X1:=X1*X2");WriteLn;
END;
BefehlsLst:="bX10:p(X1);X1:X2;wX10#0dbU1;X10:p(X10);ee";
BerechneQuad(BefehlsLst,QuadLst2);
FOR i:=1 TO 9 DO X[i]:=Y[i]; END;
BerUnterPrg(VarEins,Tiefe+1,QuadLst2,ZeigeUnterPrg);
FOR i:=1 TO 9 DO Y[i]:=X[i]; END;
END;
IF VarEins = 4 THEN
IF ZeigeUnterPrg THEN
WriteString(" U4 ---> Division : X1:=X1 DIV X2");WriteLn;
END;
BefehlsLst:="bX10:0;X11:s(X1);X12:X1;X1:X11;U2;X11:X1;X1:X12;wX11#0dbU2;X10:s(X10);X11:s(X1);X12:X1;X1:X11;U2;X11:X1;X1:X12eX1:X10e";
BerechneQuad(BefehlsLst,QuadLst);
(*Drucke(BefehlsLst,QuadLst);WriteLn;*)
FOR i:=1 TO 9 DO X[i]:=Y[i]; END;
BerUnterPrg(VarEins,Tiefe+1,QuadLst2,ZeigeUnterPrg);
FOR i:=1 TO 9 DO Y[i]:=X[i]; END;
END;
IF VarEins = 5 THEN
IF ZeigeUnterPrg THEN
WriteString(" U5 ---> Modular : X1:=X1 MOD X2");WriteLn;
END;
BefehlsLst:="bX10:0;X11:s(X1);X12:X1;X1:X11;U2;X11:X1;X1:X12;wX11#0dbU2;X10:s(X10);X11:s(X1);X12:X1;X1:X11;U2;X11:X1;X1:X12ee";
BerechneQuad(BefehlsLst,QuadLst);
FOR i:=1 TO 9 DO X[i]:=Y[i]; END;
BerUnterPrg(VarEins,Tiefe+1,QuadLst2,ZeigeUnterPrg);
FOR i:=1 TO 9 DO Y[i]:=X[i]; END;
END;
Zaehler:=QuadLst[Zaehler].IFzeile;
Korrekt:=TRUE;
ELSE
HoleVariable(QuadLst,Zaehler,VarEins,VarZwei);
Y[Max]:=X[Max];
END;
IF NOT(Korrekt) AND succ(QuadLst[Zaehler]) THEN
IF Y[VarZwei] # 65535 THEN
Y[VarEins]:=Y[VarZwei]+1;
ELSE
Y[VarEins]:=65535;
END;
Korrekt:=TRUE;
Zaehler:=QuadLst[Zaehler].IFzeile;
IF ZeigeUnterPrg THEN
WriteString(" succ(X");
WriteCard(VarZwei,1);
WriteString(") ---> X");
WriteCard(VarEins,1);
WriteString(" = ");
WriteCard(Y[VarEins],1);WriteLn;
END;
END;
IF NOT(Korrekt) AND pred(QuadLst[Zaehler]) THEN
IF Y[VarZwei] # 0 THEN
Y[VarEins]:=Y[VarZwei]-1;
ELSE
Y[VarEins]:=0;
END;
Korrekt:=TRUE;
Zaehler:=QuadLst[Zaehler].IFzeile;
IF ZeigeUnterPrg THEN
WriteString(" pred(X");
WriteCard(VarZwei,1);
WriteString(") ---> X");
WriteCard(VarEins,1);
WriteString(" = ");
WriteCard(Y[VarEins],1);WriteLn;
END;
END;
IF NOT(Korrekt) AND schleife(QuadLst[Zaehler]) THEN
IF Y[VarEins] # Y[VarZwei] THEN
Zaehler:=QuadLst[Zaehler].IFzeile;
IF ZeigeUnterPrg THEN
WriteString(" while X");
WriteCard(VarEins,1);
WriteString(" # ");
IF VarZwei = Max THEN
WriteCard(Y[Max],1);
ELSE
Write("X");
WriteCard(VarZwei,1);
END;
WriteString(" ---> TRUE");
WriteLn;
END;
ELSE
Zaehler:=QuadLst[Zaehler].ELSEzeile;
IF ZeigeUnterPrg THEN
WriteString(" while X");
WriteCard(VarEins,1);
WriteString(" # ");
IF VarZwei = Max THEN
WriteCard(Y[Max],1);
ELSE
Write("X");
WriteCard(VarZwei,1);
END;
WriteString(" ---> FALSE");
WriteLn;
END;
END;
Korrekt:=TRUE;
END;
IF NOT(Korrekt) THEN
Y[VarEins]:=Y[VarZwei];
Korrekt:=TRUE;
Zaehler:=QuadLst[Zaehler].IFzeile;
IF ZeigeUnterPrg THEN
WriteString(" X");
WriteCard(VarEins,1);
WriteString(":=");
IF VarZwei = Max THEN
WriteCard(Y[Max],1);
ELSE
Write("X");
WriteCard(VarZwei,1);
END;
WriteString(" ---> X");
WriteCard(VarEins,1);
WriteString(" = ");
WriteCard(Y[VarEins],1);
WriteLn;
END;
END;
INC(Anzahl);
INC(AnzAnweisungen);
END;
FOR i:=0 TO 9 DO
X[i]:=Y[i];
END;
END BerUnterPrg;
PROCEDURE Unterprogramm(ZeigeBefehl, ZeigeUnterPrg : BOOLEAN;
Nummer : CARDINAL);
VAR QuadLst : arrQuad;
BefehlsLst : arrList;
BEGIN
IF Nummer = 1 THEN
IF ZeigeBefehl THEN
WriteString(" U1 ---> Addition : X1:=X1+X2");WriteLn;
END;
BefehlsLst:="bX10:X2;wX10#0dbX10:p(X10);X1:s(X1)ee";
BerechneQuad(BefehlsLst,QuadLst);
BerUnterPrg(Nummer,1,QuadLst,ZeigeUnterPrg);
END;
IF Nummer = 2 THEN
IF ZeigeBefehl THEN
WriteString(" U2 ---> Subtraktion : X1:=X1-X2");WriteLn;
END;
BefehlsLst:="bX10:X2;wX10#0dbX10:p(X10);X1:p(X1)ee";
BerechneQuad(BefehlsLst,QuadLst);
BerUnterPrg(Nummer,1,QuadLst,ZeigeUnterPrg);
END;
IF Nummer = 3 THEN
IF ZeigeBefehl THEN
WriteString(" U3 ---> Multiplikation : X1:=X1*X2");WriteLn;
END;
BefehlsLst:="bX10:p(X1);X1:X2;wX10#0dbU1;X10:p(X10);ee";
BerechneQuad(BefehlsLst,QuadLst);
BerUnterPrg(Nummer,1,QuadLst,ZeigeUnterPrg);
END;
IF Nummer = 4 THEN
IF ZeigeBefehl THEN
WriteString(" U4 ---> Division : X1:=X1 DIV X2");WriteLn;
END;
BefehlsLst:="bX10:0;X11:s(X1);X12:X1;X1:X11;U2;X11:X1;X1:X12;wX11#0dbU2;X10:s(X10);X11:s(X1);X12:X1;X1:X11;U2;X11:X1;X1:X12eX1:X10e";
BerechneQuad(BefehlsLst,QuadLst);
(*Drucke(BefehlsLst,QuadLst);WriteLn;*)
BerUnterPrg(Nummer,1,QuadLst,ZeigeUnterPrg);
END;
IF Nummer = 5 THEN
IF ZeigeBefehl THEN
WriteString(" U5 ---> Modular : X1:=X1 MOD X2");WriteLn;
END;
BefehlsLst:="bX10:0;X11:s(X1);X12:X1;X1:X11;U2;X11:X1;X1:X12;wX11#0dbU2;X10:s(X10);X11:s(X1);X12:X1;X1:X11;U2;X11:X1;X1:X12ee";
BerechneQuad(BefehlsLst,QuadLst);
BerUnterPrg(Nummer,1,QuadLst,ZeigeUnterPrg);
END;
IF (Nummer < 1) AND (Nummer > 5) THEN
WriteString(" U");WriteCard(Nummer,1);
WriteString(" existiert nicht!!!");
WriteLn;
END;
END Unterprogramm;
PROCEDURE Interpreter(QuadListe : arrQuad);
VAR i,
VarEins,
VarZwei,
Anw, (* Bisher ausgefuehrte Anweisungen. *)
AnwMax, (* Maximal auszufuehrende Anweisungen *)
Zaehler : CARDINAL; (* Zeigt auf die auszufuehrende Quadrupelzeile *)
ZeigeBefehl,
ZeigeUnterPrg,
ZeigeVariable,
Korrekt : BOOLEAN;
BEGIN
FOR i:=0 TO Max DO;
X[i]:=0;
END;
WriteLn;
WriteString("Soll dieses while-Programm ausgefuehrt werden ? ");
IF JaNein() THEN
Zaehler:=1;
WriteString("Wieviele Anweisungen sollen maximal ausgefuehrt werden : ");
ReadCard(AnwMax);
IF AnwMax >= 65534 THEN AnwMax:=65534 END;
WriteCard(AnwMax,1);WriteLn;
WriteString("Soll jede einzelne Anweisung gedruckt werden ? ");
ZeigeBefehl:=JaNein();
IF ZeigeBefehl THEN
WriteString("Sollen dann auch die Variablen # 0 gedruckt werden ? ");
ZeigeVariable:=JaNein();
WriteString("Sollen die Anweisungen der Unterprogramme gezeigt ");
WriteString("werden ? ");
ZeigeUnterPrg:=JaNein();
ELSE
ZeigeVariable:=FALSE;
END;
Anw:=1;
AnzAnweisungen:=0;
WHILE Anw <= AnwMax DO
Korrekt:=FALSE;
IF QuadListe[Zaehler].Zeile = 0 THEN
WriteLn;
WriteString("Ende der Quadrupelliste --> Ende des Programms.");
WriteLn;
Korrekt:=TRUE;
Anw:=AnwMax + 1;
ELSE
IF ZeigeBefehl THEN
WriteString("Main : ");WriteCard(Anw,3);
WriteString(" Quad : ");
DruckeQuadrupel(QuadListe[Zaehler]);
END;
IF QuadListe[Zaehler].Befehl[1] = "U" THEN
Unterprogramm(ZeigeBefehl,ZeigeUnterPrg,
UnterprogrammNr(QuadListe[Zaehler]));
Zaehler:=QuadListe[Zaehler].IFzeile;
Korrekt:=TRUE;
ELSE
HoleVariable(QuadListe,Zaehler,VarEins,VarZwei);
END;
IF NOT(Korrekt) AND succ(QuadListe[Zaehler]) THEN
IF X[VarZwei] # 65535 THEN
X[VarEins]:=X[VarZwei]+1;
ELSE
X[VarEins]:=65535;
END;
Korrekt:=TRUE;
Zaehler:=QuadListe[Zaehler].IFzeile;
IF ZeigeBefehl THEN
WriteString(" succ(X");
WriteCard(VarZwei,1);
WriteString(") ---> X");
WriteCard(VarEins,1);
WriteString(" = ");
WriteCard(X[VarEins],1);WriteLn;
END;
END;
IF NOT(Korrekt) AND pred(QuadListe[Zaehler]) THEN
IF X[VarZwei] # 0 THEN
X[VarEins]:=X[VarZwei]-1;
ELSE
X[VarEins]:=0;
END;
Korrekt:=TRUE;
Zaehler:=QuadListe[Zaehler].IFzeile;
IF ZeigeBefehl THEN
WriteString(" pred(X");
WriteCard(VarZwei,1);
WriteString(") ---> X");
WriteCard(VarEins,1);
WriteString(" = ");
WriteCard(X[VarEins],1);WriteLn;
END;
END;
IF NOT(Korrekt) AND schleife(QuadListe[Zaehler]) THEN
IF X[VarEins] # X[VarZwei] THEN
Zaehler:=QuadListe[Zaehler].IFzeile;
IF ZeigeBefehl THEN
WriteString(" while X");
WriteCard(VarEins,1);
WriteString(" # ");
IF VarZwei = Max THEN
WriteCard(X[Max],1);
ELSE
Write("X");
WriteCard(VarZwei,1);
END;
WriteString(" ---> TRUE");
WriteLn;
END;
ELSE
Zaehler:=QuadListe[Zaehler].ELSEzeile;
IF ZeigeBefehl THEN
WriteString(" while X");
WriteCard(VarEins,1);
WriteString(" # ");
IF VarZwei = Max THEN
WriteCard(X[Max],1);
ELSE
Write("X");
WriteCard(VarZwei,1);
END;
WriteString(" ---> FALSE");
WriteLn;
END;
END;
Korrekt:=TRUE;
END;
IF NOT(Korrekt) THEN
X[VarEins]:=X[VarZwei];
Korrekt:=TRUE;
Zaehler:=QuadListe[Zaehler].IFzeile;
IF ZeigeBefehl THEN
WriteString(" X");
WriteCard(VarEins,1);
WriteString(":=");
IF VarZwei = Max THEN
WriteCard(X[Max],1);
ELSE
Write("X");
WriteCard(VarZwei,1);
END;
WriteString(" ---> X");
WriteCard(VarEins,1);
WriteString(" = ");
WriteCard(X[VarEins],1);
WriteLn;
END;
END;
IF ZeigeVariable THEN
DruckeVariable(X);
WriteLn;
END;
INC(AnzAnweisungen);
INC(Anw);
END;
END;
WriteLn;WriteLn;
WriteString("Es wurden ");WriteLongCard(AnzAnweisungen,1);
WriteString(" Anweisungen ausgefuehrt.");WriteLn;
WriteString("Ergebnis : ");WriteLn;
DruckeVariable(X);
END;
END Interpreter;
END QuadInterpreter.